package com.likong.iotsdk;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ParseException;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.io.UnsupportedEncodingException;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

public class ServerConnectionManager {
    private static String serviceIp = null;
    private static DeviceType deviceType;
    private static IotServerCallback iotServerCallback;
    private static RoomInfo roomInfo;
    private MqttClient mqttClient;
    private static String uuid = UUID.randomUUID().toString().replaceAll("-", "");
    private SharedPreferences sharedPreferences;


    private static ServerConnectionManager serverConnectionManager;

    private ServerConnectionManager(DeviceType deviceType) {
        this.deviceType = deviceType;
    }

    public static ServerConnectionManager getInstance(DeviceType deviceType) {
        if (serverConnectionManager == null) {
            serverConnectionManager = new ServerConnectionManager(deviceType);
        }
        return serverConnectionManager;
    }



    public  void searchAndConnectSever(Context context, IotServerCallback iotServerCallback) {
        ServerConnectionManager.iotServerCallback = iotServerCallback;
        sharedPreferences=context.getSharedPreferences("school_iot",0);
        String serverConfig=sharedPreferences.getString("serverConfig",null);
        if(serverConfig!=null&&serverConfig.length()>0){
            String[] serverConfigArr=serverConfig.split(":");
            serviceIp=serverConfigArr[0];
            new Thread(new Runnable() {
                @Override
                public void run() {
                    ServerConnectionManager.iotServerCallback.onServerFound(serverConfigArr[0],serverConfigArr[1],false);
                    connectMqttServer();
                }
            }).start();
            Timer timer=new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    if(mqttClient!=null&&(!mqttClient.isConnected())){
                        connectMqttServer();
                    }
                }
            },15000,30000);
            return ;
        }
    }


    private  MyNetInfo getMyNetInfo() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (InterfaceAddress interfaceAddress : intf.getInterfaceAddresses()) {
                    if (interfaceAddress.getBroadcast() != null) {
                        return new MyNetInfo(interfaceAddress.getAddress().getHostAddress(), interfaceAddress.getBroadcast().toString().substring(1));
                    }
                }
            }
        } catch (SocketException ex) {
            ex.printStackTrace();
        }
        return null;
    }


    private  void connectMqttServer() {
        Log.e("MqttService","连接MQTT："+serviceIp);
        if (mqttClient != null) {
            try {
                mqttClient.close(true);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        try {
            mqttClient = new MqttClient("tcp://" + serviceIp + ":1883", "terminal_"+(new Date()).getTime(), new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            options.setUserName("leectrl_terminal");
            options.setPassword("LikongTerminal2018".toCharArray());
            // 设置超时时间
            options.setConnectionTimeout(10);
            // 设置会话心跳时间
            options.setKeepAliveInterval(20);
            options.setAutomaticReconnect(false);
            mqttClient.connect(options);
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    Log.e("MqttService", "onDisconnected");
                    if (ServerConnectionManager.iotServerCallback != null) {
                        ServerConnectionManager.iotServerCallback.onServerDisconnected();
                    }
                }

                @Override
                public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                    String topicStr = topic;
                    String payloadStr = null;
                    try {
                        payloadStr = (new String(mqttMessage.getPayload(), "UTF-8"));
                        Log.e("MqttService", topicStr + "==>" + payloadStr);
                        String[] topicArr = topicStr.split("/");

                        if (topicArr.length == 6 && uuid.equals(topicArr[4])) {
                            JSONObject object = JSONObject.parseObject(payloadStr);
                            roomInfo = new RoomInfo();
                            roomInfo.setRoomId(object.getIntValue("room_id"));
                            roomInfo.setRoomName(object.getString("room_name"));
                            if (ServerConnectionManager.iotServerCallback != null) {
                                ServerConnectionManager.iotServerCallback.onReceiveRoomInfo(roomInfo);
                            }
                            unsubscribeTopic("/iot/tx/terminal/" + uuid + "/" + deviceType.getDeviceType());
                        } else {
                            if (ServerConnectionManager.iotServerCallback != null) {
                                ServerConnectionManager.iotServerCallback.onReceiveMessage(topicStr, payloadStr);
                            }
                        }
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

                }

            });
            if (ServerConnectionManager.iotServerCallback != null) {
                ServerConnectionManager.iotServerCallback.onServerConnected();
            }
            String roomInfoStr = sharedPreferences.getString("room_info", null);
            if (roomInfoStr != null) {
                roomInfo = JSON.parseObject(roomInfoStr, RoomInfo.class);

                if (ServerConnectionManager.iotServerCallback != null) {
                    ServerConnectionManager.iotServerCallback.onReceiveRoomInfo(roomInfo);
                }
            } else {
                subscribeTopic("/iot/tx/terminal/" + uuid + "/" + deviceType.getDeviceType());
                JSONObject jsonObject = new JSONObject();
                MyNetInfo netInfo = getMyNetInfo();
                jsonObject.put("ip", netInfo.getIpAddress());
                String message = JSONObject.toJSONString(jsonObject);
                publishMessage("/iot/rx/terminal/" + uuid + "/" + deviceType.getDeviceType(), message);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void publishMessage(String msg){
        try {
            if(mqttClient!=null&&mqttClient.isConnected()&&roomInfo!=null){
                MqttMessage message = new MqttMessage();
                message.setQos(1);
                message.setRetained(true);
                message.setPayload(msg.getBytes());
                MqttTopic mqttTopic = mqttClient.getTopic("/ctrl/rx/room/" + roomInfo.getRoomId() + "/dev/controller");
                MqttDeliveryToken token = mqttTopic.publish(message);//发布主题
                token.waitForCompletion();
            }

        } catch (MqttPersistenceException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (MqttException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }

    public void publishMessage(String topic,String msg){
        try {
            if(mqttClient.isConnected()){
                MqttMessage message = new MqttMessage();
                message.setQos(1);
                message.setRetained(true);
                message.setPayload(msg.getBytes());
                MqttTopic mqttTopic = mqttClient.getTopic(topic);
                MqttDeliveryToken token = mqttTopic.publish(message);//发布主题
                token.waitForCompletion();
            }

        } catch (MqttPersistenceException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (MqttException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }


    public  void subscribeTopic(String topicStr) {
        // Subscribe to a topic foo
        try {
            mqttClient.subscribe(topicStr);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    public  void unsubscribeTopic(String topicStr) {
        // Subscribe to a topic foo
        try {
            mqttClient.unsubscribe(topicStr);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }


}
